// 微信 JSSDK 辅助（H5 环境）
// 函数风格：const xxx = () => {}
import { netConfig } from "@/api/net.config";
// 签名接口地址（由后端实现返回 appId/timestamp/nonceStr/signature）
const WECHAT_SIGN_URL = netConfig.baseURL + "/auth/wechatsignature";
const WX_JSSDK_URL = "http://res.wx.qq.com/open/js/jweixin-1.6.0.js";

let wxSdkLoadingPromise: Promise<void> | null = null;

// 确保窗口上挂载的是微信 JSSDK 的 wx 对象
const ensureWxInstance = (): boolean => {
  if (typeof window === "undefined") return false;
  const globalObj = window as any;
  if (globalObj.wx && typeof globalObj.wx.config === "function") return true;
  if (globalObj.jWeixin && typeof globalObj.jWeixin.config === "function") {
    globalObj.wx = globalObj.jWeixin;
    return true;
  }
  return false;
};

// 判断是否在微信内置浏览器
export const isWeixinH5 = (): boolean => {
  if (typeof window === "undefined") return false;
  return /MicroMessenger/i.test(window.navigator.userAgent || "");
};

interface WxSignResp {
  appId: string;
  timestamp: number;
  nonceStr: string;
  signature: string;
}

// 向后端请求签名（需服务端实现）
export const fetchWxSignature = (url: string): Promise<WxSignResp> => {
  return new Promise((resolve, reject) => {
    uni.request({
      url: WECHAT_SIGN_URL,
      data: { url },
      success: (res) => {
        const data: any = res.data || {};
        const s = data.result || data;
        if (s && s.appId && s.timestamp && s.nonceStr && s.signature)
          resolve(s);
        else reject(new Error("invalid wx sign resp"));
      },
      fail: (e) => reject(e),
    });
  });
};

// 动态加载微信 JSSDK，确保只加载一次
export const loadWxJssdk = (): Promise<void> => {
  if (typeof window === "undefined") {
    return Promise.reject(new Error("非浏览器环境无法加载微信 JSSDK"));
  }
  if (ensureWxInstance()) return Promise.resolve();
  if (wxSdkLoadingPromise) return wxSdkLoadingPromise;

  wxSdkLoadingPromise = new Promise<void>((resolve, reject) => {
    const handleLoad = () => {
      if (ensureWxInstance()) {
        resolve();
      } else {
        wxSdkLoadingPromise = null;
        reject(new Error("微信 JSSDK 未正确挂载"));
      }
    };
    const handleError = () => {
      wxSdkLoadingPromise = null;
      reject(new Error("微信 JSSDK 加载失败"));
    };

    const exists = document.querySelector(
      `script[src="${WX_JSSDK_URL}"]`
    ) as HTMLScriptElement | null;
    if (exists) {
      exists.addEventListener("load", handleLoad, { once: true });
      exists.addEventListener("error", handleError, { once: true });
      // 已加载的脚本不会再次触发 load，需主动校验
      const state = exists.readyState;
      if (state === "complete" || state === "loaded") {
        handleLoad();
      }
      return;
    }

    const script = document.createElement("script");
    script.src = WX_JSSDK_URL;
    script.async = true;
    script.onload = handleLoad;
    script.onerror = handleError;
    (document.head || document.body || document.documentElement).appendChild(
      script
    );
  });

  return wxSdkLoadingPromise;
};

// 初始化 JSSDK
export const initWxSdk = async ({
  jsApi,
  openTag,
}: {
  jsApi?: string;
  openTag?: string;
}): Promise<void> => {
  await loadWxJssdk();

  const pageUrl =
    typeof window !== "undefined" ? window.location.href.split("#")[0] : "";
  const sign = await fetchWxSignature(pageUrl);
  // @ts-ignore

  return new Promise((resolve, reject) => {
    wx.config({
      debug: false,
      appId: sign.appId,
      timestamp: sign.timestamp,
      nonceStr: sign.nonceStr,
      signature: sign.signature,
      // jsApiList: [
      // "openLocation",
      // "getLocation",
      // "scanQRCode",
      // ],
      jsApiList: jsApi ? [jsApi] : [],
      openTagList: openTag ? [openTag] : [],
    });
    wx.ready(() => resolve());
    wx.error((err: any) => reject(err));
  });
};
